跳到主要内容

创建第一个 ROS2 功能包

ROS2 功能包

功能包是 ROS2 代码的组织单元。如果想构建代码或与他人共享,那么需要将代码组织在一个功能包中。通过功能包,用户可以发布 ROS2 成果。

ROS2 使用 ament 作为功能包的构建系统,使用 colcon 作为其构建工具。用户可以使用CMake 或 Python 创建一个功能包,这些都是官方支持的。

ROS2 Python 和 CMake 功能包各自有其最低要求的内容:

CMake功能包内容

  • CMakeLists.txt 文件,描述如何构建功能包内的代码

  • include/<package_name> 目录,包含功能包的公共头文件

  • package.xml 文件,包含有关功能包的元信息

  • src 目录,包含功能包的源代码

python功能包内容

  • package.xml 文件:包含有关功能包的元信息。

  • resource/<package_name> 标记文件:用于标记功能包,使ROS 2工具能够识别。

  • setup.cfg 文件:当功能包包含可执行文件时必需,以便ros2 run可以找到它们。

  • setup.py 文件:包含安装功能包的指令。

  • <package_name> 目录:与功能包同名的目录,用于ROS 2工具查找功能包,包含 __init__.py 文件。

最简单的功能包的文件结构可能如下所示:

my_package/
CMakeLists.txt
include/my_package/
package.xml
src/
my_package/
package.xml
resource/my_package
setup.cfg
setup.py
my_package/

创建并构建功能包

单个工作空间可以包含任意数量的功能包,每个功能包都有自己的文件夹。用户也可以在同一个工作空间中拥有不同构建类型的功能包(CMake、Python等),但不能有嵌套功能包。

一个简单的工作空间可能如下所示:

ros2_ws/
src/
cpp_package_1/
CMakeLists.txt
include/cpp_package_1/
package.xml
src/

py_package_1/
package.xml
resource/py_package_1
setup.cfg
setup.py
py_package_1/
...
cpp_package_n/
CMakeLists.txt
include/cpp_package_n/
package.xml
src/

创建功能包

首先,加载ros底层环境。

source /opt/ros/jazzy/setup.bash

在创建的工作空间 ros2_ws 来创建新功能包。确保现在位于 src 文件夹中,在 ROS2中创建新功能包的命令语法是:

ros2 pkg create --build-type ament_cmake <package_name>
ros2 pkg create --build-type ament_python <package_name>

在终端中输入以下命令:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 --node-name my_node my_package_cpp
ros2 pkg create --build-type ament_python --license Apache-2.0 --node-name my_node my_package_py

--node-name--license 为可选参数,--node-name 选项在功能包中创建一个简单的 Hello World 类型的可执行文件,--license 声明功能包的许可信息。现在,工作空间的 src 目录中新建一个名为 my_package 的新文件夹。

运行命令后,该终端将返回创建的具体文件的名称。

构建功能包

返回到工作空间的根目录:

cd ~/ros2_ws

使用如下命令构建工作空间的所有功能包:

colcon build

当工作空间中只有几个功能包时,使用该命令没有问题。但是当有许多功能包时,colcon build 可能需要很长时间。如果只构建 my_package 功能包,可以运行:

colcon build --packages-select my_package_cpp

加载工作空间并使用

要运行新功能包和可执行文件,首先打开一个新的终端并加载主要ROS 2安装。

然后,在 ros2_ws 目录内,运行以下命令来加载工作空间:

source install/local_setup.bash

现在工作空间已被添加到路径中,现在可以使用新功能包中的可执行文件。

要运行功能包创建期间使用--node-name 参数创建的可执行文件,输入命令:

ros2 run my_package_cpp my_node

将在终端返回消息:

hello world my_package package

查看功能包内容

ros2_ws/src/my_package_cpp 内,我们将看到 ros2 pkg create 自动生成的文件和文件夹:

CMakeLists.txt  include  package.xml  src

my_node.cpp 位于 src 目录内,存放所有自定义C++节点源文件。

my_package  package.xml  resource  setup.cfg  setup.py  test

my_node.py 位于 my_package_py 目录内, 存放所有自定义python节点源文件。

自定义package.xml

在功能包创建成功后,会在终端返回提示消息,其中 descriptionlicense 字段包含 TODO 注释。 这是因为功能包描述和许可声明不是自动设置的,在发布功能包之前需要填写这些信息。

ros2_ws/src/my_package_cpp打开package.xml文件:

<?xml version="1.0"?>
<?xml-model
href="http://download.ros.org/schema/package_format3.xsd"
schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_package</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="user@todo.todo">user</maintainer>
<license>TODO: License declaration</license>

<buildtool_depend>ament_cmake</buildtool_depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>

ros2_ws/src/my_package_py打开package.xml文件:

<?xml version="1.0"?>
<?xml-model
href="http://download.ros.org/schema/package_format3.xsd"
schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_package</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="user@todo.todo">user</maintainer>
<license>TODO: License declaration</license>

<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>

<export>
<build_type>ament_python</build_type>
</export>
</package>

maintainer行上输入姓名和电子邮件, 编辑description行总结功能包:

<description>Beginner client libraries tutorials practice package</description>

然后,更新 license<license>Apache License 2.0</license>。 这些信息的填写并不对程序运行产生影响。编辑完成后,记得保存。

在license标签下方,会有一些以 _depend 结尾的标签名。 这是 package.xml 列出了对其他功能包的依赖项,供colcon搜索。 my_package_cppmy_package_py 很简单,没有任何依赖项。对于 CMake 形式的功能包到此结束。如果使用 python 还有setup.py 的配置。

setup.py 文件包含与 package.xml 具有相同的描述、维护者和许可证字段,因此用户也需要设置这些字段,这些信息在两个文件中必须完全匹配。版本和名称(package_name)也需要完全匹配,并且应该在两个文件中自动填充。

编辑setup.py 文件

使用文本编辑器打开 setup.py 文件。

from setuptools import find_packages, setup

package_name = 'my_py_pkg'

setup(
name=package_name,
version='0.0.0',
packages=find_packages(exclude=['test']),
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='TODO',
maintainer_email='TODO',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'my_node = my_py_pkg.my_node:main'
],
},
)

编辑 maintainermaintainer_email, 和 description 匹配  package.xml 内容。

本章小结

本章介绍了 ROS2 工作空间和功能包的基本概念与使用方法,讲解了底层环境与覆盖环境的关系,以及工作空间的创建、构建和加载流程。通过 colcon 构建工具,读者了解了 ROS 2 工程的基本目录结构及其作用。

同时,本章说明了 C++ 与 Python 功能包的基本结构和创建方式,并简要介绍了功能包元信息文件的配置要点。通过实践示例,读者能够完成从创建功能包到运行节点的完整流程,为后续 ROS 2 编程学习奠定基础。